{
	UCE - cross-platform game engine written in delphi.
	Copyright (c) 2009, Shutko Vitaly

	This file is part of UCE.

	UCE is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	UCE is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
}

unit uTim;

interface

uses
{$IFDEF WIN32}
  Windows,
{$ELSE}
  Unix,
{$ENDIF}
  uTyp;

type
  TTim = class(TListItem)
    active: Boolean;
    stepSize, targetTime: Cardinal;
    onStepProc: TProc;

    procedure OnStep; virtual;

    constructor Create(stepSize: Cardinal = 30; onStepProc: Pointer = nil; active: Boolean = True);
  end;

  TTimMan = class(TList)
    time: Cardinal;

    function Add(tim: TTim): TTim; overload;
    function Add(name: String; stepSize: Cardinal = 30; onStepProc: Pointer = nil; active: Boolean = True): TTim; overload;
    function Find(name: String): TTim;
    procedure Rem(tim: TTim);

    function GetTime: Cardinal;
    procedure Update;

    destructor Destroy; override;
  end;

implementation

constructor TTim.Create(stepSize: Cardinal = 30; onStepProc: Pointer = nil; active: Boolean = True);
begin
  Self.active := active;
  Self.stepSize := stepSize;
  Self.onStepProc := onStepProc;
end;

procedure TTim.OnStep; begin end;

destructor TTimMan.Destroy;
begin
  Free_;
end;

function TTimMan.Add(tim: TTim): TTim;
begin
  Result := TTim(inherited Add(tim));
  Result.targetTime := GetTime + tim.stepSize;
end;

function TTimMan.Add(name: String; stepSize: Cardinal = 30; onStepProc: Pointer = nil; active: Boolean = True): TTim;
begin
  Result := TTim.Create;
  Result.name := name;
  Result.active := active;
  Result.stepSize := stepSize;
  Result.onStepProc := onStepProc;
  
  Add(Result);
end;

function TTimMan.Find(name: String): TTim;
begin
  Result := TTim(inherited Find(name));
end;

procedure TTimMan.Rem(tim: TTim);
begin
  inherited Rem(tim);
  tim.Free;
end;

function TTimMan.GetTime: Cardinal;
{$IFNDEF WIN32}
var
  tv: timeval;
{$ENDIF}
begin
{$IFDEF WIN32}
  Result := GetTickCount;
{$ELSE}
  fpGetTimeOfDay(@tv, nil);
  Result := tv.tv_sec * 1000 + tv.tv_usec div 1000;
{$ENDIF}
end;

procedure TTimMan.Update;
var
  i: Integer;
begin
  time := GetTime;

  for i := 0 to size - 1 do
    if items[i] <> nil then
      if TTim(items[i]).active and (TTim(items[i]).targetTime <= time) then
      begin
        TTim(items[i]).targetTime := GetTime + TTim(items[i]).stepSize;
        TTim(items[i]).OnStep;

        if @TTim(items[i]).onStepProc <> nil then
          TTim(items[i]).onStepProc;
      end;
end;

end.
